﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calc {
	public class Equation {
		private IComputable operation;

		public Equation(IComputable operation) {
			this.operation = operation;
		}

		public static Equation Create(string expression) {
			Equation result = null;

			result = new Equation(CreateIComputable(expression));

			return result;
		}

		protected static IComputable CreateIComputable(string expression) {
			IComputable result = null;

			int add = expression.IndexOf('+');
			int substract = expression.IndexOf('-');
			int minAS = Math.Min(add, substract);

			if (minAS >= 0) {
				if (add < substract) {
					if (minAS < expression.Length - 1)
						result = new Operation(CreateIComputable(expression.Substring(0, minAS)), Operations.Multiply, CreateIComputable(expression.Substring(minAS + 1)));
				} else {
					if (minAS < expression.Length - 1)
						result = new Operation(CreateIComputable(expression.Substring(0, minAS)), Operations.Divide, CreateIComputable(expression.Substring(minAS + 1)));
				}
			} else if (add >= 0) {
				if (add < expression.Length - 1)
					result = new Operation(CreateIComputable(expression.Substring(0, add)), Operations.Add, CreateIComputable(expression.Substring(add + 1)));
			} else if (substract >= 0) {
				if (substract < expression.Length - 1)
					result = new Operation(CreateIComputable(expression.Substring(0, substract)), Operations.Subtract, CreateIComputable(expression.Substring(substract + 1)));
			} else {
				int multiply = expression.IndexOf('*');
				int divide = expression.IndexOf('/');
				int minMD = Math.Min(multiply, divide);

				if (minMD >= 0) {
					if (multiply < divide) {
						if (minMD < expression.Length - 1)
							result = new Operation(CreateIComputable(expression.Substring(0, minMD)), Operations.Multiply, CreateIComputable(expression.Substring(minMD + 1)));
					} else {
						if (minMD < expression.Length - 1)
							result = new Operation(CreateIComputable(expression.Substring(0, minMD)), Operations.Divide, CreateIComputable(expression.Substring(minMD + 1)));
					}
				} else if (multiply >= 0) {
					if (multiply < expression.Length - 1)
						result = new Operation(CreateIComputable(expression.Substring(0, multiply)), Operations.Multiply, CreateIComputable(expression.Substring(multiply + 1)));
				} else if (divide >= 0) {
					if (divide < expression.Length - 1)
						result = new Operation(CreateIComputable(expression.Substring(0, divide)), Operations.Divide, CreateIComputable(expression.Substring(divide + 1)));
				} else {
					decimal number;
					if (decimal.TryParse(expression, out number))
						result = new Number(number);
					else
						result = new Parameter(expression);
				}
			}

			return result;
		}

		public bool TryCompute(out decimal result) {
			return this.operation.TryGetValue(out result);
		}

		public bool TryResolve(out string resultExpression) {
			resultExpression = this.operation.GetEquation( );
			return true;
		}
	}
}
